﻿using System.Reflection;
using System;
using System.Linq;
using Castle.Windsor.Installer;

namespace Inovout
{
    public class ComponentAssembly
    {
        private Assembly assembly;
        private ComponentRegistry componentRegistry;
        public ComponentAssembly(ComponentRegistry componentRegistry,Assembly assembly)
        {
            this.componentRegistry = componentRegistry;
            this.assembly = assembly;
            this.type = GetComponentAssemblyType();
        }
        private ComponentAssemblyType type;
        public ComponentAssemblyType Type
        {
            get { return type; }
        }

        private ComponentAssemblyType GetComponentAssemblyType()
        {
            if (CheckFrameworkAssembly())
            {
      
                return ComponentAssemblyType.Framework;
            }
            else if (CheckModuleAssembly())
            {
                return ComponentAssemblyType.Business;
            }
            else
            {
                return ComponentAssemblyType.Basic;
            }
        }
        internal void Load()
        {
            if (type == ComponentAssemblyType.Framework)
            {
                componentRegistry.Container.Install(FromAssembly.Instance(assembly));
            }
            else if(type == ComponentAssemblyType.Business)
            {
                //前提所有Framework的dll必须加载完毕
                foreach (ComponentRegistrar componentInstaller in componentRegistry.Container.ResolveAll<ComponentRegistrar>())
                {
                    //componentInstaller.isDebug = ComponentRegistry.IsDebug;
                    componentInstaller.Register(assembly);
                }
            }
        }
        private static readonly string[] basicAssemblyCompanies = new string[] {
        "Microsoft Corporation","NUnit.org","Castle Project","Adolfo Marinucci","NHibernate.org","The Apache Software Foundation"
        };

        private static readonly Assembly coreAssembly = typeof(ComponentRegistry).Assembly;
        
        private bool CheckModuleAssembly()
        {
            AssemblyCompanyAttribute assemblyCompanyAttribute =
                Attribute.GetCustomAttribute(assembly, typeof(AssemblyCompanyAttribute)) as AssemblyCompanyAttribute;
            //if (assemblyCompanyAttribute.Company == "Adolfo Marinucci")
            //{
            //    //AvalonDock Adolfo Marinucci
            //    throw new Exception();
            //}
            return assemblyCompanyAttribute != null && !basicAssemblyCompanies.Contains(assemblyCompanyAttribute.Company);
        }
  
        private bool CheckFrameworkAssembly()
        {
            return Attribute.GetCustomAttribute(coreAssembly, typeof(AssemblyCompanyAttribute)).Equals(
                Attribute.GetCustomAttribute(assembly, typeof(AssemblyCompanyAttribute))
                ) &&
                ByteArrayEquals(coreAssembly.GetName().GetPublicKey(), assembly.GetName().GetPublicKey());
        }

        private bool ByteArrayEquals(byte[] source, byte[] target)
        {
            if (!source.Length.Equals(target.Length))
            {
                return false;
            }
            for (int i = 0; i < source.Length; i++)
            {
                if (!source[i].Equals(target[i]))
                {
                    return false;
                }

            }
            return true;
        }

    }
}
